// Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <sstream>
#include <vector>
#include <map>
#include "CasLog.h"
#include "CasAppCtrlCmdUtils.h"

using namespace std;

static vector<string> Split(const string &s, const string &separator)
{
    vector<string> result;
    typedef string::size_type StringSize;
    StringSize i = 0;

    while (i != s.size()) {
        int flag = 0;
        while (i != s.size() && flag == 0) {
            flag = 1;
            for (char x : separator) {
                if (s[i] == x) {
                    ++i;
                    flag = 0;
                    break;
                }
            }
        }

        flag = 0;
        StringSize j = i;
        while (j != s.size() && flag == 0) {
            for (char x : separator) {
                if (s[j] == x) {
                    flag = 1;
                    break;
                }
                if (flag == 0) {
                    ++j;
                }
            }
        }
        if (i != j) {
            result.push_back(s.substr(i, j - i));
            i = j;
        }
    }
    return result;
}

static std::string ParametersToString(std::map<std::string, std::string> parameters,
    std::string separator = COMMAND_SEPARATOR)
{
    std::string ret = "";
    int count = 0;
    for (auto it = parameters.begin(); it != parameters.end(); it++) {
        count++;
        ret += it->first + "=" + it->second;
        if (count != static_cast<int>(parameters.size())) {
            ret += separator;
        }
    }
    return ret;
}

std::map<string, string> CasAppCtrlCmdUtils::ParseCommand(const char *data, int length, std::string separator)
{
    map<string, string> ret;
    ret.clear();
    if (data == nullptr) {
        ERR("Parse command error, data is null");
        return ret;
    }
    if (length < 9) {
        ERR("Parse command error, data length too short, length = %d", length);
        return ret;
    }
    string line(data, length);
    vector<string> records = Split(line, separator);
    for (uint64_t i = 0; i < records.size(); i++) {
        string record = records[i];
        // 解决base64字段的=问题
        size_t pos = record.find_first_of('=', 0);
        if (pos > 0 && pos < record.length()) {
            string key = record.substr(0, pos);
            string value = record.substr(pos + 1);
            ret[key] = value;
        } else {
            ret.clear();
            return ret;
        }
    }
    return ret;
}

string CasAppCtrlCmdUtils::MakeCommand(map<string, string> parameters, std::string separator)
{
    return ParametersToString(parameters, separator);
}